home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 118_01.zip / ROFF2.BDS < prev    next >
Text File  |  1993-06-03  |  18KB  |  1,049 lines

  1. /* software tools format program -- C version -- Part 2
  2.  * source:  roff2.bds
  3.  * version: November 26, 1981.
  4.  */
  5.  
  6. #include tools.h        /* defs for primitives */
  7. #include roff.h
  8.  
  9. /*    finit - set parameters to default values */
  10.  
  11. finit()
  12. {
  13.     /* include: cparam, cpage, cout, cdefio, cnr, cmac */
  14.     int  i;
  15.  
  16.     /* initialize flags */
  17.     cuflag = NO;
  18.     dir = 0;
  19.     putflag = NO;
  20.  
  21.     /* initialize cparam */
  22.     inval = 0;
  23.     rmval = PAGEWIDTH;
  24.     tival = 0;
  25.     lsval = 1;
  26.     fill = YES;
  27.     ceval = 0;
  28.     ulval = 0;
  29.     boval = 0;
  30.     cchar = '.';
  31.     tjust [0] = LEFT;
  32.     tjust [1] = CENTER;
  33.     tjust [2] = RIGHT;
  34.     bsval = 0;
  35.     rjust = YES;
  36.     cuval = 0;
  37.     for (i = 0; i < INSIZE; i++) {
  38.         if (i % 8 == 0) {
  39.             tabs [i] = YES;
  40.         }
  41.         else {
  42.             tabs [i] = NO;
  43.         }
  44.     }
  45.  
  46.     /* initialize cpage */
  47.     lineno = 0;
  48.     curpag = 0;
  49.     newpag = 1;
  50.     plval = PAGELEN;
  51.  
  52.     m1val = 3;
  53.     m2val = 2;
  54.     m3val = 2;
  55.     m4val = 3;
  56.     bottom = plval - m3val - m4val;
  57.  
  58.     ehead [0] = NEWLINE;
  59.     ehead [1] = EOS;
  60.     ohead [0] = NEWLINE;
  61.     ohead [1] = EOS;
  62.  
  63.     efoot [0] = NEWLINE;
  64.     efoot [1] = EOS;
  65.     ofoot [0] = NEWLINE;
  66.     ofoot [1] = EOS;
  67.  
  68.     ehlim [0] = inval;
  69.     ehlim [1] = rmval;
  70.     ohlim [0] = inval;
  71.     ohlim [1] = rmval;
  72.  
  73.     eflim [0] = inval;
  74.     eflim [1] = rmval;
  75.     oflim [0] = inval;
  76.     oflim [1] = rmval;
  77.  
  78.     stopx = NO;
  79.     frstpg = 0;
  80.     lastpg = HUGE;
  81.     print = YES;
  82.     offset = 0;
  83.  
  84.     /* initialize cout */
  85.     outp = 0;
  86.     outw = 0;
  87.     outwds = 0;
  88.  
  89.     /* initialize dynamic storage */
  90.  
  91.     /* ----- calling sequence changed ----- */
  92.     dsinit();
  93.  
  94.     /* initialize symbol table for macros */
  95.  
  96.     /* ----- calling sequence changed */
  97.     mactbl = mktabl(29);
  98.  
  99.     /* initialize cdefio */
  100.     bp = -1;
  101.  
  102.     /* initialize cnr */
  103.     for (i = 0; i < 26; i++) {
  104.         nr [i] = 0;
  105.     }
  106. }
  107.  
  108.  
  109. /*    gettl - copy title from buf to ttl */
  110.  
  111. gettl(buf, ttl, lim)
  112. char *buf, *ttl;
  113. int  *lim;
  114. {
  115.     /* include: cparam */
  116.     int  i;
  117.  
  118.     /* skip command name */
  119.     i = 0;
  120.     while ( buf [i] != ' ' &&
  121.             buf [i] != TAB &&
  122.             buf [i] != NEWLINE
  123.           ) {
  124.         i++;
  125.     }
  126.  
  127.     /* skip to start of title */
  128.     skipbl(buf, &i);
  129.  
  130.     /* copy titles to ttl */
  131.     scopy(buf, i, ttl, 0);
  132.  
  133.     /* comment out ----- gettl trace
  134.     printf("gettl:  buf is -->%s\n",buf);
  135.     printf("gettl:  ttl is -->%s\n",ttl);
  136.     printf("Hit any key to continue\n");
  137.     getch(SYS_TERM);
  138.     ----- end comment out */
  139.  
  140.     /* set limits */
  141.     lim [0] = inval;
  142.     lim [1] = rmval;
  143. }
  144.  
  145. /*    getval - evaluate optional numeric argument
  146.  *             set i past argument
  147.  *             set argtype to type (numeric or not)
  148.  *             calling sequence:  getval (buf, &i, &argtyp);
  149.  */
  150.  
  151. getval(buf, i, argtyp)
  152. char *buf;
  153. int  *i, *argtyp;
  154. {
  155.     /* move *i past blanks */
  156.     skipbl(buf, i);
  157.     *argtyp = buf [*i];
  158.     if (*argtyp == '+' || *argtyp == '-') {
  159.         (*i)++;
  160.     }
  161.     /* move *i past argument */
  162.     return(ctoi(buf, i));
  163. }
  164.  
  165. /*    getwrb - get  a word; hangs onto trailing blanks
  166.  *             point i past word
  167.  *             calling sequence:  getwrb (in, &i, out);
  168.  */
  169.  
  170. getwrb(in, ii, out)
  171. char *in, *out;
  172. int *ii;
  173. {
  174.     int  i, j;
  175.  
  176.     i = *ii;
  177.     j = 0;
  178.     while ( in [i] != EOS &&
  179.             in [i] != ' ' &&
  180.             in [i] != TAB &&
  181.             in [i] != NEWLINE
  182.           ) {
  183.         out [j++] = in [i++];
  184.     }
  185.  
  186.     /* include trailing blanks */
  187.     while (in [i] == ' ') {
  188.         i++;
  189.         out [j++] = ' ';
  190.     }
  191.  
  192.     /* supply a blank to end the word if none there */
  193.     if ( j > 0 && out [j - 1] != ' ') {
  194.         out [j++] = ' ';
  195.     }
  196.  
  197.     out [j] = EOS;
  198.     *ii = i;
  199.  
  200.     /* comment out ----- getwrb trace
  201.     printf("getwrb:  out = %s, i = %d, j = %d\n",out,i,j);
  202.     printf("Hit any key to continue\n");
  203.     getch(SYS_TERM);
  204.     ----- end comment out */
  205.  
  206.     return(j);
  207. }
  208.  
  209. /*    gfield - get next tab or title field
  210.  *             set i past field
  211.  *             return number of characters copied
  212.  *         calling sequence: gfield(buf, &i, n, temp, delim);
  213.  */
  214.  
  215. int gfield(buf, ii, n, temp, delim)
  216. char *buf;
  217. int *ii;
  218. int  n;
  219. char *temp;
  220. char delim;
  221. {
  222.     int  i, j;
  223.  
  224.     i = *ii;
  225.     j = 0;
  226.     if (n > 0) {
  227.         if (buf [i] == delim) {
  228.             i++;
  229.         }
  230.         while ( buf [i] != delim &&
  231.                 buf [i] != EOS &&
  232.                 buf [i] != NEWLINE &&
  233.                 j < n
  234.               ) {
  235.             temp [j++] = buf [i++];
  236.         }
  237.     }
  238.  
  239.     /* skip things between delims */
  240.     while ( buf [i] != delim &&
  241.             buf [i] != EOS &&
  242.             buf [i] != NEWLINE
  243.           ) {
  244.         i++;
  245.     }
  246.  
  247.     temp [j] = EOS;
  248.     *ii = i;
  249.     return(j);
  250. }
  251.  
  252. /*    jcopy - scopy without copying EOS */
  253.  
  254. jcopy(from, i, to, j)
  255. char *from, *to;
  256. int i, j;
  257. {
  258.     while (from [i] != EOS) {
  259.         to [j++] = from [i++];
  260.     }
  261. }
  262.  
  263. /*    justify - justifies string in its tab column */
  264.  
  265. justify(in, left, right, type, out)
  266. char *in, *out;
  267. int left, right, type;
  268. {
  269.     int j, n;
  270.  
  271.     n = width(in);
  272.     if (type == RIGHT) {
  273.         j = max ( (right - n), 0);
  274.         jcopy(in, 0, out, j);
  275.     }
  276.     else if (type == CENTER) {
  277.         j = max( (right + left - n) / 2, left);
  278.         jcopy(in, 0, out, j);
  279.     }
  280.     else jcopy(in, 0, out, left);
  281.  
  282.     /* comment out ----- justify trace
  283.     printf("justify: type = %d\n out = %s\n",type,out);
  284.     printf("Hit any key to continue\n");
  285.     getch(SYS_TERM);
  286.     ----- end comment out */
  287. }
  288.  
  289. /*    leadbl - delete leading blanks, set tival */
  290.  
  291. leadbl(buf)
  292. char *buf;
  293. {
  294.     /* include: cparam */
  295.     int  i, j;
  296.  
  297.     brk();
  298.  
  299.     /* find first non-blank character on the line */
  300.     for (i = 0; buf [i] == ' '; i++) {
  301.         ;
  302.     }
  303.     if (buf [i] != NEWLINE) {
  304.         tival += i;
  305.     }
  306.  
  307.     /* move line to left */
  308.     j = 0;
  309.     while ((buf [j++] = buf [i++])!= EOS) {
  310.         ;
  311.     }
  312. }
  313.  
  314. /*    ludef - look up a macro name
  315.  *            copy the definition to defn
  316.  *            return pointer to definition if found.
  317.  *            Note:  this is a change in lookup.
  318.  */
  319.  
  320. ludef (name, defn)
  321. char *name, *defn;
  322. {
  323.     /* include: cmac */
  324.     int  i;
  325.     char *locn;
  326.  
  327.     /* comment out -----
  328.     printf("in ludef:  name = %s\n",name);
  329.     ----- end comment out */
  330.  
  331.     if ((locn = lookup (name, mactbl)) == 0) {
  332.         return (NO);
  333.     }
  334.     else {
  335.         scopy (locn, 0, defn, 0);
  336.         return (YES);
  337.     }
  338. }
  339.  
  340. /*    ngetch - get a char from file fd or
  341.  *             the stack of pushed back characters.
  342.  */
  343.  
  344. ngetch(fd)
  345. int  fd;
  346. {
  347.     /* include: cdefio */
  348.  
  349.     if (bp >= 0) {
  350.         return(pbbuf [bp--]);
  351.     }
  352.     else {
  353.         return(getch(fd));
  354.     }
  355. }
  356.  
  357. /*    ngetln - get next line from f into line */
  358.  
  359. ngetln(line, fd)
  360. char *line;
  361. int fd;
  362. {
  363.     int  i;
  364.     int  c;
  365.  
  366.     i = 0;
  367.     while (i < MAXLINE - 1 && (c = ngetch(fd)) != EOF) {
  368.         line [i++] = c;
  369.         if (c == NEWLINE) {
  370.             break;
  371.         }
  372.     }
  373.     line [i] = EOS;
  374.     if (i == 0 && c == EOF) {
  375.         i = EOF;
  376.     }
  377.     return(i);
  378. }
  379.  
  380. /*  pbstr - push string back onto input */
  381.  
  382. pbstr(in)
  383. char *in;
  384. {
  385.     int  i;
  386.  
  387.     for (i = length(in) - 1; i >= 0; i--)
  388.         putbak(in [i]);
  389. }
  390.  
  391. /*    pfoot - put out page footer */
  392.  
  393. pfoot()
  394. {
  395.     /* include: cpage */
  396.  
  397.     skip(m3val);
  398.     if (m4val > 0) {
  399.         if (curpag % 2 == 0) {
  400.             puttl(efoot, eflim, curpag);
  401.         }
  402.         else {
  403.             puttl(ofoot, oflim, curpag);
  404.         }
  405.  
  406.         /* comment out ----- pagecontrol
  407.         ifnotdef(PAGECONTROL,  skip(m4val-1) );
  408.         ----- end comment out */
  409.  
  410.         skip(m4val-1);
  411.     }
  412. }
  413.  
  414. /*    phead - put out page header */
  415.  
  416. phead()
  417. {
  418.     /* include: cpage */
  419.     int  c [MAXLINE];
  420.  
  421.     curpag = newpag;
  422.  
  423.     /* check whether we should print this page */
  424.     if (curpag >= frstpg && curpag <= lastpg) {
  425.         print = YES;
  426.     }
  427.     else {
  428.         print = NO;
  429.     }
  430.     if (stopx == YES && print == YES) {
  431.         prmpt();
  432.     }
  433.     newpag++;
  434.  
  435.     /* comment out ---------- pagecontrol
  436.     ifdef(PAGECONTROL,
  437.             if (stopx == 0 && print == YES) {
  438.                 putc(PAGEJECT);
  439.             }
  440.           )
  441.     ---------- end comment out */
  442.  
  443.     if (m1val > 0) {
  444.         skip(m1val-1);
  445.         if (curpag % 2 == 0) {
  446.             puttl(ehead, ehlim, curpag);
  447.         }
  448.         else {
  449.             puttl(ohead, ohlim, curpag);
  450.         }
  451.     }
  452.     skip(m2val);
  453.     lineno = m1val + m2val + 1;
  454. }
  455.  
  456. /*    prmpt - pause for paper insertion. */
  457.  
  458. prmpt()
  459. {
  460.     char line [MAXLINE];
  461.  
  462.     putlin("Type return to begin a page",SYS_TERM);
  463.     getlin(line, SYS_TERM);
  464. }
  465.  
  466. /*    put - put out line
  467.  *          ALL output eventually comes here via
  468.  *          calls from text() or calls from brk().
  469.  */
  470.  
  471. put(buf)
  472. char *buf;
  473. {
  474.     if (lineno == 0 || lineno > bottom) {
  475.         phead();
  476.     }
  477.     if (print == YES) {
  478.         put1(buf);
  479.     }
  480.     tival = inval;
  481.     skip (min (lsval - 1, bottom - lineno));
  482.     lineno += lsval;
  483.     if (lineno > bottom) {
  484.         pfoot();
  485.     }
  486. }
  487.  
  488. /*    put1 - put out text beteen header and footer */
  489.  
  490. put1(buf)
  491. char *buf;
  492. {
  493.  
  494.     /* include: cpage, cparam */
  495.     int  i, j, w, c;
  496.     int  start;
  497.  
  498.     /* comment out ----- put1 trace
  499.     printf("put1:  buf = %s\n",buf);
  500.     printf("Hit any key to continue\n");
  501.     getch(SYS_TERM);
  502.     ----- end comment out */
  503.  
  504.     /* putflag may be YES on entry */
  505.  
  506.     w = 0;
  507.     start = 0;
  508.  
  509.     /* page offset */
  510.     for (i = 0; i < offset; i++) {
  511.         putc(' ');
  512.     }
  513.  
  514.     /* indentation */
  515.     for (i = 0; i < tival; i++) {
  516.         putc(' ');
  517.     }
  518.  
  519.     /* put out line. handle underlining */
  520.  
  521.     for ( i = 0; ;i++) {
  522.         c = buf [i];
  523.         if ( (putflag == NO) &&
  524.              (c == EOS || c == NEWLINE)
  525.            ) {
  526.             break;
  527.         }
  528.  
  529.         if (c == STARTU) {
  530.             start = i + 1;
  531.             w = 0;
  532.             putflag = YES;
  533.         }
  534.         else if (c == STOPU && putflag == NO) {
  535.             remark("in put1: extra STOPU ignored");
  536.         }
  537.         else if ( c == STOPU ||
  538.                   c == EOS ||
  539.                   c == NEWLINE
  540.                 ) {
  541.             /* output chars */
  542.             for (j = start; j < i ;j++) {
  543.                 putch(buf[j], STDOUT);
  544.             }
  545.             /* now backspace */
  546.             for (j = 0; j < w; j++) {
  547.                 putch(BACKSPACE, STDOUT);
  548.             }
  549.             /* now underline */
  550.             for (j = 0; j < w; j++) {
  551.                 putch('_', STDOUT);
  552.             }
  553.             if (c == EOS || c == NEWLINE) {
  554.                 break;
  555.             }
  556.             putflag = NO;
  557.         }
  558.         else if (putflag == YES) {
  559.             w += widthch(c);
  560.         }
  561.         else {
  562.             putch(c, STDOUT);
  563.         }
  564.     } /* end of for loop */
  565.  
  566.     putch(NEWLINE, STDOUT);
  567. }
  568.  
  569. /*    putbak - push character back onto input */
  570.  
  571. putbak(c)
  572. char c;
  573. {
  574.     /* include: cdefio */
  575.  
  576.     if (++bp >= PBSIZE) {
  577.         error("too many characters pushed back.");
  578.     }
  579.     pbbuf [bp] = c;
  580. }
  581.  
  582. /*    puttl - put out title line
  583.  *            substitute line number for '#'
  584.  *            substitute date for '%'
  585.  */
  586.  
  587. puttl(buf, lim, pageno)
  588. char *buf;
  589. int *lim;
  590. int pageno;
  591. {
  592.     /* include cpage, cparam, ctemp */
  593.     char chars [MAXLINE], cdate[MAXLINE];
  594.     char delim;
  595.     int  nc, i, j, n, left, right, ncd;
  596.     char *now;
  597.  
  598.     if (print == NO) {
  599.         return;
  600.     }
  601.     left = lim [0];
  602.     right = lim [1];
  603.  
  604.     /* calculate the width of the page number and date */
  605.     nc = itoc(pageno, chars, MAXLINE - 1);
  606.     now = getnow();
  607.  
  608.     fmtdat(cdate, tbuf1, now, 0);
  609.     ncd = length(cdate);
  610.  
  611.     delim = buf [0];
  612.  
  613.     /* blank out title field */
  614.     for (j = 0; j < right; j++) {
  615.         ttl [j] = ' ';
  616.     }
  617.  
  618.     /* get the left, center, and right fields */
  619.     
  620.     i = 0;
  621.     for(n = 0; n < 3 ;n++ ) {
  622.  
  623.         /* get next field of title */
  624.         if ( gfield ( buf, &i, right - left,
  625.                       tbuf1, delim) > 0 ) {
  626.             
  627.             /* substitute page num for '#' */
  628.             subst ( tbuf1, PAGENUM, tbuf2,
  629.                     chars, nc);
  630.  
  631.             /* substitute date for '%' */
  632.             subst ( tbuf2, CURRENTDATE, tbuf1,
  633.                     cdate, ncd);
  634.  
  635.             justify ( tbuf1, left, right,
  636.                       tjust [n], ttl);
  637.         }
  638.         if ( buf [i] == EOS ||
  639.              buf [i] == NEWLINE
  640.            ) {
  641.             break;
  642.         }
  643.     }
  644.  
  645.     /* trim blanks */
  646.     while (ttl [right-1] == ' ') {
  647.         right--;
  648.     }
  649.     ttl [right] = NEWLINE;
  650.     ttl [right+1] = EOS;
  651.  
  652.     /* offset title */
  653.     for (i = 0; i < offset; i++) {
  654.         putc(' ');
  655.     }
  656.  
  657.     /* output title */
  658.     putlin(ttl, STDOUT);
  659. }
  660.  
  661. /*    putwrd - put a word in outbuf
  662.  *             the word includes trailing blanks
  663.  *             justify right margin when line becomes full
  664.  */
  665.  
  666. putwrd(wrdbuf)
  667. char *wrdbuf;
  668. {
  669.     /* include cout, cparam */
  670.     int  last, llval, nextra, len, w;
  671.  
  672.     len = length(wrdbuf);
  673.     w = width(wrdbuf);
  674.  
  675.     /* set new end of outbuf */
  676.     last = len + outp;
  677.     llval = rmval - tival;
  678.  
  679.     if (outw + w > llval || last >= MAXOUT) {
  680.         /* too big -- buffer will have one word */
  681.         last = len;
  682.  
  683.         /* do not allow trailing blanks on a line */
  684.         nextra = llval - outw;
  685.         while ( outp > 0 && 
  686.                 outbuf[outp - 1] == ' '
  687.               ) {
  688.             outp--;
  689.             nextra++;
  690.         }
  691.  
  692.         /* outp points past the last char or 0 here */
  693.  
  694.         if (rjust == YES) {
  695.             spread(outbuf, outp, nextra, outwds);
  696.             if (nextra > 0 && outwds > 1) {
  697.                 outp += nextra;
  698.             }
  699.         }
  700.         brk();        /*  flush previous line */
  701.     }
  702.     scopy(wrdbuf, 0, outbuf, outp);
  703.     outp = last;
  704.     outw += w;
  705.     outwds++;
  706. }
  707.  
  708. /*    set - set parameter and check range */
  709.  
  710. set( param, val, argtyp, defval, minval, maxval)
  711. int *param, val, argtyp, defval, minval, maxval;
  712. {
  713.  
  714.     if (argtyp == NEWLINE) {
  715.         /* use default */
  716.         *param = defval;
  717.     }
  718.     else if (argtyp == '+') {
  719.         /* increase */
  720.         *param += val;
  721.     }
  722.     else if (argtyp == '-') {
  723.         /* decrease */
  724.         *param -= val;
  725.     }
  726.     else {
  727.         /* set to new value */
  728.         *param = val;
  729.     }
  730.     /* put value in bounds */
  731.     *param = min(*param, maxval);
  732.     *param = max(*param, minval);
  733. }
  734.  
  735. /*    skip - output  n  blank lines */
  736.  
  737. skip(n)
  738. int  n;
  739. {
  740.     /* include cpage */
  741.  
  742.     if (print == YES) {
  743.         while (n-- > 0) {
  744.             putc(NEWLINE);
  745.         }
  746.     }
  747. }
  748.  
  749. /*    space - space  n  lines or to bottom of page */
  750.  
  751. space(n)
  752. int  n;
  753. {
  754.     /* include: cpage */
  755.  
  756.     brk();
  757.     if (lineno > bottom) {
  758.         return;
  759.     }
  760.     if (lineno == 0) {
  761.         phead();
  762.     }
  763.     skip(min(n, bottom + 1 - lineno));
  764.     lineno += n;
  765.     if (lineno > bottom) {
  766.         pfoot();
  767.     }
  768. }
  769.  
  770. /*    spread - spread words to justify right margin
  771.  *               warning:  this routine is sensitive to
  772.  *             bad parameters.
  773.  */
  774.  
  775. spread(buf, outp, ne, outwds)
  776. char *buf;
  777. int outp, ne, outwds;
  778. {
  779.     /* include: cparam */
  780.     int  i, j, nb, nholes;
  781.  
  782.     /* comment out ----- spread trace
  783.     printf("spread:  outp = %d,  ",outp);
  784.     printf("ne = %d,  ",ne);
  785.     printf("outwds = %d  \n",outwds);
  786.     printf("spread: buf = %s\n",buf);
  787.     printf("Hit any key to continue\n");
  788.     getch(SYS_TERM);
  789.     ----- end comment out */
  790.  
  791.     if (ne <= 0 || outwds <= 1 || outp <= 0) {
  792.         return;
  793.     }
  794.  
  795.     /* reverse direction */
  796.     dir = 1 - dir;
  797.  
  798.     nholes = outwds - 1;
  799.     if (tival != inval && nholes > 1) {
  800.         nholes--;
  801.     }
  802.  
  803.     /* point i at last character of buf */
  804.     i = outp - 1;
  805.  
  806.     /* leave room for NEWLINE and EOS */
  807.     j = min(MAXOUT - 2, i + ne);
  808.  
  809.     while (i < j) {
  810.         buf [j] = buf [i];
  811.         if (buf [i] == ' ' && buf [i-1] != ' ') {
  812.             if (dir == 0) {
  813.                 nb = (ne-1) / nholes + 1;
  814.             }
  815.             else {
  816.                 nb = ne / nholes;
  817.             }
  818.             ne = ne - nb;
  819.             nholes--;
  820.             while (nb-- > 0) {
  821.                 buf [--j] = ' ';
  822.             }
  823.         }
  824.         i--;
  825.         j--;
  826.         if (i < 0 || j < 0) {
  827.             sys_error("spread:\n");
  828.         }
  829.     }
  830. }
  831.  
  832. /*    subst - substitute a string for char1 */
  833.  
  834. subst(in, char1, out, subara, n)
  835. char *in, *out, *subara;
  836. char char1;
  837. int  n;
  838. {
  839. int  i, j, k;
  840.  
  841.     for (i = 0, j = 0; in [i] != EOS; i++) {
  842.         if (in [i] == char1) {
  843.             for (k = 0; k < n; ) {
  844.                 out [j++] = subara [k++];
  845.             }
  846.         }
  847.         else {
  848.             out [j++] = in [i];
  849.         }
  850.     }
  851.     out [j] = EOS;
  852.  
  853.     /* comment out ----- subst trace
  854.     printf("subst: char = %c,  out = %s\n",char1,out);
  855.     printf("Hit any key to continue\n");
  856.     getch(SYS_TERM);
  857.     ----- end comment out */
  858.  
  859. }
  860.  
  861. /*    text - process text lines */
  862.  
  863. text(inbuf)
  864. char *inbuf;
  865. {
  866.     /* include cparam */
  867.     char wrdbuf [INSIZE];
  868.     int  i;
  869.  
  870.     /* data cuflag /NO/ */
  871.  
  872.     /* expand escapes */
  873.     doesc(inbuf, wrdbuf, INSIZE);
  874.  
  875.     /* expand tabs */
  876.     dotabs(inbuf, wrdbuf, INSIZE);
  877.  
  878.     if (inbuf [0] == ' ' || inbuf [0] == NEWLINE) {
  879.         /* move left, set tival */
  880.         leadbl(inbuf);
  881.     }
  882.  
  883.     if (ulval > 0) {
  884.         /* word underlining */
  885.         underl(inbuf, wrdbuf, INSIZE);
  886.         ulval--;
  887.     }
  888.  
  889.     if (cuval > 0) {
  890.         /* continuous underlining */
  891.         if (cuflag == NO) {
  892.             scopy(inbuf, 0, wrdbuf, 0);
  893.             inbuf [0] = STARTU;
  894.             scopy(wrdbuf, 0, inbuf, 1);
  895.             cuflag = YES;
  896.         }
  897.         cuval--;
  898.         if (cuflag == YES && cuval == 0) {
  899.             /* overwrite \n and EOS */
  900.             i = length(inbuf) - 1;
  901.             inbuf [i] = STOPU;
  902.             inbuf [i+1] = NEWLINE;
  903.             inbuf [i+2] = EOS;
  904.             cuflag = NO;
  905.         }
  906.     }
  907.     if (boval >  0) {
  908.         /* boldfacing */
  909.         bold(inbuf, wrdbuf, INSIZE);
  910.         boval--;
  911.     }
  912.  
  913.     if (ceval >  0) {
  914.         /* centering */
  915.         center(inbuf);
  916.         put(inbuf);
  917.         ceval--;
  918.     }
  919.     else if (inbuf [0] == NEWLINE) {
  920.         /* all blank line */
  921.         put(inbuf);
  922.     }
  923.     else if (fill == NO) {
  924.         /* unfilled textd */
  925.         put(inbuf);
  926.     }
  927.     else {
  928.         /* filled text */
  929.  
  930.         /* comment out ----- text trace
  931.         printf("text:  inbuf = %s\n",inbuf);
  932.         printf("Hit any character to continue\n");
  933.         getch(SYS_TERM);
  934.         ----- end comment out */
  935.  
  936.         /* insure two spaces after a period */
  937.         i = length(inbuf);
  938.         inbuf [i] = ' ';
  939.         if (inbuf [i-1] == '.') {
  940.             inbuf [++i] = ' ';
  941.         }
  942.         inbuf [i+1] = EOS;
  943.         for (i = 0; getwrb(inbuf, &i, wrdbuf) > 0; )
  944.             putwrd(wrdbuf);
  945.     }
  946. }
  947.  
  948. /*    underl - underline words in a line
  949.  *             surround each word with STARTU and STOPU
  950.  */
  951.  
  952. underl(buf, tbuf, size)
  953. char *buf, *tbuf;
  954. int size;
  955. {
  956.     int  i, j, t;
  957.     int inword;
  958.  
  959.     inword = NO;
  960.  
  961.     /* use tbuf as internal buffer */
  962.     for (i = 0, j = 0; j < size - 3; ) {
  963.         if (buf [i] == EOS || buf [i] == NEWLINE) {
  964.             break;
  965.         }
  966.         t = tolower(type(buf[i]));
  967.  
  968.         if (inword == NO) {
  969.             /* look for start of word */
  970.             if (t == 'a' || t == '0' || t == '_') {
  971.                 /* add STARTU to buffer */
  972.                 tbuf [j++] = STARTU;
  973.                 inword = YES;
  974.             }
  975.         }
  976.         else {
  977.             /* look for end of word */
  978.             if (t != 'a' && t != '0' && t != '_') {
  979.                 /* add STOPU to buffer */
  980.                 tbuf [j++] = STOPU;
  981.                 inword = NO;
  982.             }
  983.         }
  984.         /* always copy the character */
  985.         tbuf [j++] = buf [i++];
  986.     }
  987.  
  988.     /* make sure we end outside underline mode */
  989.     if (inword == YES) {
  990.         tbuf [j++] = STOPU;
  991.     }
  992.  
  993.     tbuf [j++] = NEWLINE;
  994.     tbuf [j]   = EOS;
  995.  
  996.     /* put result back in tbuf */
  997.     scopy(tbuf, 0, buf, 0);
  998.  
  999.     /* comment out ----- underl trace
  1000.     printf("underl: buf is: %s\n",buf);
  1001.     ----- end comment out */
  1002. }
  1003.  
  1004. /*    width - return width of character string */
  1005.  
  1006. int width(buf)
  1007. char *buf;
  1008. {
  1009.     int  value;
  1010.  
  1011.     value = 0;
  1012.     while (*buf != EOS) {
  1013.         value += widthch(*buf++);
  1014.     }
  1015.     return(value);
  1016. }
  1017.  
  1018. /* return width of a character */
  1019.  
  1020. widthch(c)
  1021. int c;
  1022. {
  1023.  
  1024.     if (c == BACKSPACE) {
  1025.         return(-1);
  1026.     }
  1027.     else if (c >= ' ' && c <= '~') {
  1028.         return(1);
  1029.     }
  1030.     else {
  1031.         return(0);
  1032.     }
  1033. }
  1034. ---- underl trace
  1035.     printf("underl: buf is: %s\n",buf);
  1036.     ----- end comment out */
  1037. }
  1038.  
  1039. /*    width - return width of character string */
  1040.  
  1041. int width(buf)
  1042. char *buf;
  1043. {
  1044.     int  value;
  1045.  
  1046.     value = 0;
  1047.     while (*buf != EOS) {
  1048.         value += widthch(*buf++);
  1049.     }